/*-
 * Copyright (c) 2013 Shang-Rong Cai. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $ NUMTK: dblbk.c    Rev. 0.0.2    2013-11-06T12:22+08:00 $
 */

#include <stdlib.h>
#include <stdio.h>

#include <bscerr.h>

#include <numtk.h>

int didk_init(size_t rz, size_t cz, size_t kz, didk_t *bk)
{
    int ierr = ERRNO_UNDEFINED;

    bk->r_sz = rz;
    bk->c_sz = cz;
    bk->e_sz = 0;
    bk->k_sz = kz;

    bk->item = (didbl_t*) calloc(bk->k_sz, sizeof(didbl_t));

    return ierr;
}


int didk_dest(didk_t *bk)
{
    int ierr = ERRNO_UNDEFINED;

    bk->r_sz = 0;
    bk->c_sz = 0;
    bk->e_sz = 0;
    bk->k_sz = 0;

    free(bk->item);

    return ierr;
}


void didk_stdout(didk_t *bk)
{
    size_t zi;

    for (zi = 0; zi < bk->e_sz; zi++)
    {
        printf("%6zd: (%6d, %6d) % .14le\n", zi, bk->item[zi].r_idx, bk->item[zi].c_idx, bk->item[zi].value);
    }
}


int cidk_init(size_t rz, size_t cz, size_t kz, uint8_t flg, cidk_t *bk)
{
    int ierr = ERRNO_UNDEFINED;
    size_t ptrz;

    ptrz = 0;

    bk->r_sz = rz;
    bk->c_sz = cz;
    bk->e_sz = 0;
    bk->k_sz = kz;

    bk->flag = flg;

    switch (bk->flag)
    {
        case ROW_WISE:
            ptrz = bk->r_sz;
            break;
        case COL_WISE:
            ptrz = bk->c_sz;
            break;
        case RDR_NONE:
            ierr = ERRNO_SUPPORT_NONE;
            goto EXIT_CIDK_INIT;
            break;
        default:
            ierr = ERRNO_UNKNOWN_TYPE;
            goto EXIT_CIDK_INIT;
            break;

    }

    bk->sptr = (sidxpair_t*) calloc(ptrz, sizeof(sidxpair_t));
    bk->item = (cidbl_t*) calloc(bk->k_sz, sizeof(cidbl_t));

    EXIT_CIDK_INIT:

    return ierr;
}


int cidk_dest(cidk_t *bk)
{
    int ierr = ERRNO_UNDEFINED;

    bk->r_sz = 0;
    bk->c_sz = 0;
    bk->e_sz = 0;
    bk->k_sz = 0;

    bk->flag = RDR_NONE;

    free(bk->item);

    return ierr;
}


int cidk_stdout(cidk_t *bk)
{
    int ierr = ERRNO_UNDEFINED;

    size_t zi;
    sidx_t si;

    size_t cmpidxz;  /* Compressed index size */
    size_t cnt;

    switch (bk->flag)
    {
        case ROW_WISE:
            cmpidxz = bk->r_sz;
            break;
        case COL_WISE:
            cmpidxz = bk->c_sz;
            break;
        case RDR_NONE:
            ierr = ERRNO_SUPPORT_NONE;
            goto EXIT_CIDK_STDOUT;
        default:
            ierr = ERRNO_UNKNOWN_TYPE;
            goto EXIT_CIDK_STDOUT;
            break;
    }

    cnt = 0;

    if (bk->flag == ROW_WISE)
    {
        for (zi = 0; zi < cmpidxz; zi++)
        {
            for (si = bk->sptr[zi].head; si < bk->sptr[zi].tail; si++)
            {
                printf("%6zd: (%6zd, %6d) % .14le\n", cnt, zi, bk->item[si].index, bk->item[si].value);
                cnt++;
            }
        }
    }
    else
    {
        for (zi = 0; zi < cmpidxz; zi++)
        {
            for (si = bk->sptr[zi].head; si < bk->sptr[zi].tail; si++)
            {
                printf("%6zd: (%6d, %6zd) % .14le\n", cnt, bk->item[si].index, zi, bk->item[si].value);
                cnt++;
            }
        }
    }

    EXIT_CIDK_STDOUT:

    return ierr;
}
